package cn.toma.service.impl.sys;

import cn.toma.common.utils.StringUtils;
import cn.toma.common.utils.Tree;
import cn.toma.common.utils.TreeUtil;
import cn.toma.common.vo.QueryRequest;
import cn.toma.core.AbstractService;
import cn.toma.dao.sys.DeptMapper;
import cn.toma.dto.DeptTree;
import cn.toma.model.sys.Dept;
import cn.toma.service.sys.DeptService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@Service("deptService")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DeptServiceImpl extends AbstractService<Dept> implements DeptService
{

	@Resource
	private DeptMapper deptMapper;


	@Override
	public Map<String, Object> findDept(QueryRequest queryRequest, Dept dept)
	{
		Map<String, Object> result = new HashMap<>();
		try {
			List<Dept> depts = findDepts(queryRequest, dept);
			List<Tree<Dept>> trees = new ArrayList<>();
			buildTrees(trees, depts);
			List<? extends Tree> deptTree = TreeUtil.build(trees);

			result.put("rows", deptTree);
			result.put("total", depts.size());
		} catch (Exception e) {
			log.error("获取部门列表失败", e);
			result.put("rows", null);
			result.put("total", 0);
		}
		return result;
	}

	@Override
	public List<Dept> findDepts(QueryRequest queryRequest, Dept dept)
	{
		Weekend<Dept> deptWeekend = new Weekend<>(Dept.class);
		WeekendCriteria<Dept, Object> weekendCriteria = deptWeekend.weekendCriteria();
		String orderBy = StringUtils.sortOrderBy(queryRequest);
		if (StringUtils.isNotEmpty(orderBy)) {
			deptWeekend.setOrderByClause(orderBy);
		}

		if (StringUtils.isNotBlank(dept.getDeptName())) {
			weekendCriteria.andLike(Dept::getDeptName, "%" + dept.getDeptName() + "%");
		}
		if (StringUtils.isNotBlank(dept.getCreateTimeFrom()) && StringUtils.isNotBlank(dept.getCreateTimeTo())) {
			weekendCriteria
					.orGreaterThanOrEqualTo(Dept::getCreateTime, dept.getCreateTimeFrom())
					.andLessThanOrEqualTo(Dept::getCreateTime, dept.getCreateTimeTo());
		}
		return deptMapper.selectByCondition(deptWeekend);
	}

	@Override
	@Transactional
	public void createDept(Dept dept)
	{
		Long parentId = dept.getParentId();
		if (parentId == null) {
			dept.setParentId(0L);
		}
		dept.setCreateTime(new Date());
		this.save(dept);
	}

	@Override
	@Transactional
	public void updateDept(Dept dept)
	{
		dept.setModifyTime(new Date());
		this.deptMapper.updateByPrimaryKeySelective(dept);
	}

	@Override
	@Transactional
	public void deleteDepts(String[] deptIds)
	{
		Arrays.stream(deptIds).forEach(deptId -> this.deptMapper.deleteDepts(deptId));
	}

	private void buildTrees(List<Tree<Dept>> trees, List<Dept> depts)
	{
		depts.forEach(dept -> {
			DeptTree tree = new DeptTree();
			tree.setId(dept.getDeptId().toString());
			tree.setParentId(dept.getParentId().toString());
			tree.setLabel(dept.getDeptName());
			tree.setOrderNum(dept.getOrderNum().intValue());
			trees.add(tree);
		});
	}
}
